from flask import Flask, render_template, redirect, url_for, session, flash, request
import mysql.connector
from config import Config
from auth import login_required, admin_required
from datetime import datetime, date, timedelta
import os
from functools import wraps

app = Flask(__name__)
app.config.from_object(Config)


# 全局上下文处理器 - 为所有模板提供网站设置
@app.context_processor
def inject_site_settings():
    """在所有模板中注入网站设置"""
    try:
        conn = get_db_connection()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("""
            SELECT * FROM site_settings 
            ORDER BY id DESC LIMIT 1
        """)
        settings = cursor.fetchone()
        
        cursor.close()
        conn.close()
        
        return dict(global_site_settings=settings)
    except Exception as e:
        # 如果数据库查询失败，返回默认值
        return dict(global_site_settings=None)


# 数据库连接
def get_db_connection():
    return mysql.connector.connect(
        host='mysql',
        user=Config.MYSQL_USER,
        password=Config.MYSQL_PASSWORD,
        database=Config.MYSQL_DB
    )


# 装饰器：更新房间计数后再执行视图函数
def update_room_counts(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        update_rooms_count_from_orders()
        return f(*args, **kwargs)

    return decorated_function


# 从订单表更新房间计数
def update_rooms_count_from_orders():
    """
    从订单表读取数据，更新房间表中的count字段
    count字段表示房间被预订的次数，用于推荐算法
    """
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)

    try:
        # 获取最近30天的订单数据，按房间分组计数
        thirty_days_ago = datetime.now() - timedelta(days=30)
        cursor.execute("""
            SELECT room_id, COUNT(*) as booking_count 
            FROM bookings
            WHERE created_at >= %s AND status != 'cancelled'
            GROUP BY room_id
        """, (thirty_days_ago,))

        room_bookings = cursor.fetchall()

        # 更新每个房间的count值
        for booking in room_bookings:
            cursor.execute("""
                UPDATE rooms 
                SET count = count + %s 
                WHERE id = %s
            """, (booking['booking_count'], booking['room_id']))

        conn.commit()
        app.logger.info(f"Updated booking counts for {len(room_bookings)} rooms")

    except Exception as e:
        conn.rollback()
        app.logger.error(f"Error updating room counts: {str(e)}")
    finally:
        cursor.close()
        conn.close()


# 主页
@app.route('/')
@update_room_counts
def index():
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)

    # 获取精选房间（3个），按count降序，优先展示预订次数多的
    cursor.execute("""
        SELECT * FROM rooms 
        WHERE status = 'available' 
        ORDER BY count DESC 
        LIMIT 3
    """)
    featured_rooms = cursor.fetchall()
    
    # 获取轮播图（仅启用的）
    cursor.execute("""
        SELECT * FROM banners 
        WHERE is_active = 1 
        ORDER BY sort_order ASC, id DESC
        LIMIT 5
    """)
    banners = cursor.fetchall()
    
    # 获取网站设置
    cursor.execute("""
        SELECT * FROM site_settings 
        ORDER BY id DESC LIMIT 1
    """)
    site_settings = cursor.fetchone()

    cursor.close()
    conn.close()

    return render_template('index.html',
                           featured_rooms=featured_rooms,
                           banners=banners,
                           site_settings=site_settings)


# 关于我们页面
@app.route('/about')
def about():
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    
    # 获取关于我们内容
    cursor.execute("""
        SELECT * FROM about_content 
        ORDER BY id DESC LIMIT 1
    """)
    about_content = cursor.fetchone()
    
    cursor.close()
    conn.close()
    
    return render_template('about.html', about_content=about_content)


# 房间列表页面 - 带有基础推荐算法
@app.route('/rooms')
@update_room_counts
def rooms():
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)

    # 获取筛选参数
    room_type = request.args.get('type', 'all')
    capacity = request.args.get('capacity', 'all')
    sort_by = request.args.get('sort', 'popularity')  # 默认按 popularity（count）排序

    # 构建查询
    query = "SELECT * FROM rooms WHERE 1=1"  # 固定条件，方便拼接其他条件
    params = []

    if room_type != 'all':
        query += " AND room_type = %s"
        params.append(room_type)

    if capacity != 'all':
        if capacity == '4':
            query += " AND capacity >= 4"
        else:
            query += " AND capacity = %s"
            params.append(capacity)

    # 添加排序条件 - 基础推荐算法
    if sort_by == 'popularity':
        # 按预订次数（count）降序，热门房间优先
        query += " ORDER BY count DESC"
    elif sort_by == 'price_asc':
        # 价格从低到高
        query += " ORDER BY price ASC"
    elif sort_by == 'price_desc':
        # 价格从高到低
        query += " ORDER BY price DESC"
    elif sort_by == 'newest':
        # 最新上架（假设有created_at字段）
        query += " ORDER BY created_at DESC"

    cursor.execute(query, params)
    rooms = cursor.fetchall()

    cursor.close()
    conn.close()

    return render_template('rooms.html',
                           rooms=rooms,
                           current_type=room_type,
                           current_capacity=capacity,
                           current_sort=sort_by)


@app.route('/rooms/<int:room_id>')
def room_detail(room_id):
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)

    try:
        # 获取房间详情
        cursor.execute("SELECT * FROM rooms WHERE id = %s", (room_id,))
        room = cursor.fetchone()

        if not room:
            flash('指定的房间不存在', 'danger')
            return redirect(url_for('rooms'))

        # 获取房间图片
        cursor.execute("""
            SELECT image_url FROM rooms 
            WHERE id = %s 
        """, (room_id,))
        room_images = cursor.fetchall()

        # 获取房间设施并按类别分组
        cursor.execute("""
            SELECT a.* FROM amenities a
            JOIN room_amenities ra ON a.id = ra.amenity_id
            WHERE ra.room_id = %s
            ORDER BY a.category, a.name
        """, (room_id,))
        room_amenities = cursor.fetchall()

        # 按类别分组设施
        amenity_categories = {}
        for amenity in room_amenities:
            category = amenity['category']
            if category not in amenity_categories:
                amenity_categories[category] = []
            amenity_categories[category].append(amenity)

        # 获取相关推荐房间 - 优先推荐同类型且热门的房间
        cursor.execute("""
            SELECT * FROM rooms 
            WHERE status = 'available' AND room_type = %s AND id != %s 
            ORDER BY count DESC
            LIMIT 2
        """, (room['room_type'], room_id))
        related_rooms = cursor.fetchall()

        # 生成未来30天的日期供预订查询
        today = date.today()
        available_dates = []
        for i in range(30):
            current_date = today + timedelta(days=i)
            # 这里简化处理，实际应查询订单表判断是否可预订
            available = True if i % 7 != 0 else False  # 示例：每7天有一天不可预订

            available_dates.append({
                'date': current_date,
                'available': available,
                'is_today': current_date == today
            })

    except Exception as e:
        flash(f'获取房间信息失败: {str(e)}', 'danger')
        return redirect(url_for('rooms'))
    finally:
        cursor.close()
        conn.close()

    return render_template('room_detail.html',
                           room=room,
                           room_images=room_images,
                           amenity_categories=amenity_categories,
                           related_rooms=related_rooms,
                           available_dates=available_dates,
                           today=today)


# 美食页面
@app.route('/cuisine')
def cuisine():
    return render_template('cuisine.html')


# 设施页面
@app.route('/facilities')
def facility():
    return render_template('facility.html')


# 交通页面
@app.route('/access')
def access():
    return render_template('access.html')


# 联系我们页面
@app.route('/contact', methods=['GET', 'POST'])
def contact():
    if request.method == 'POST':
        name = request.form['name']
        email = request.form['email']
        phone = request.form['phone']
        subject = request.form['subject']
        message = request.form['message']
        submitted_at = datetime.now()

        # 保存留言到数据库
        conn = get_db_connection()
        cursor = conn.cursor()

        try:
            cursor.execute("""
                INSERT INTO contacts (name, email, phone, subject, message, submitted_at)
                VALUES (%s, %s, %s, %s, %s, %s)
            """, (name, email, phone, subject, message, submitted_at))
            conn.commit()
            flash('感谢您的留言，我们会尽快回复您！', 'success')
        except Exception as e:
            conn.rollback()
            flash(f'提交失败：{str(e)}', 'danger')
        finally:
            cursor.close()
            conn.close()

        return redirect(url_for('contact'))

    # 获取联系信息
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute("SELECT * FROM contacts")
    contact_info = cursor.fetchone()
    cursor.close()
    conn.close()

    return render_template('contact.html', contact_info=contact_info)


# 预订查询页面
@app.route('/booking/check')
def booking_check():
    return render_template('booking_check.html')


# 导入用户和管理员路由
from user.routes import user_bp
from admin.routes import admin_bp

app.register_blueprint(user_bp, url_prefix='/user')
app.register_blueprint(admin_bp, url_prefix='/admin')

# 确保上传目录存在（修复缩进：移除多余空格，放在全局作用域）
os.makedirs(os.path.join(app.root_path, 'static', 'uploads'), exist_ok=True)

# 优化启动逻辑：仅在直接运行脚本时启动开发服务器（避免Gunicorn启动冲突）

if __name__ == "__main__":
    # 获取主机和端口配置
    host = os.environ.get('FLASK_HOST', '0.0.0.0')  # 默认绑定到所有接口
    port = int(os.environ.get('FLASK_PORT', 5000))  # 默认端口5000
    debug = os.environ.get('FLASK_DEBUG', 'False').lower() == 'true'
    
    app.run(host=host, port=port, debug=debug)

